package com.demo.cms.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;

import com.demo.cms.dao.ArticleDao;
import com.demo.cms.model.Article;
import com.demo.cms.model.ArticleContent;
import com.demo.cms.model.ArticleExtend;
import com.demo.cms.service.ArticleContentService;
import com.demo.cms.service.ArticleExtendService;
import com.demo.cms.service.ArticleService;
import com.demo.cms.service.exception.ArticleCreateException;
import com.demo.common.StringUtils;
import com.demo.core.dao.base.support.ResultSearchResult;
import com.demo.core.dao.base.support.SearchArgumentSupport;
import com.demo.security.annotation.audit.AuditNotes;
import com.demo.security.annotation.audit.PostAudit;
import com.demo.security.annotation.audit.PreAudit;

/**
 * 文章服务实现类
 * @author ryuu.kk
 *
 */
public class ArticleServiceImpl implements ArticleService {

	/**
	 * 文章数据访问Dao
	 */
	private ArticleDao articleDao;
	
	/**
	 * 文章内容服务
	 */
	private ArticleContentService articleContentService;
	
	/**
	 * 文章扩展属性服务
	 */
	private ArticleExtendService articleExtendService;
	
	@AuditNotes
	private String auditNotes;
	
	@Override
	@Transactional
	public Long save(Article article) throws ArticleCreateException {
		//内容列表
		List<ArticleContent> contentList = article.getContentList();
		//扩展属性
		List<ArticleExtend> extendList = article.getExtendList();
		//总页数
		int pageSize = contentList == null ? 0 : contentList.size();
		article.setPageCount(pageSize);
		article.setCreateDate(new Date());
		Long articleId = articleDao.insert(article);
		
		//对内容的添加
		if (contentList != null && contentList.size() > 0) {
			int index = 1;
			for(ArticleContent content : contentList) {
				// 第{n}页
				content.setIndex(index);
				content.setArticleId(articleId);
				articleContentService.add(content);
				index ++;
			}
		}
		//对扩展属性的添加
		if (article.getExtendList() != null && article.getExtendList().size() > 0) {
			for(ArticleExtend extend : extendList) {
				extend.setArticleId(articleId);
				articleExtendService.add(extend);
			}
		}
		
		return articleId;
	}

	@Override
	public boolean exists(Long id) {
		return articleDao.exists(id);
	}

	@Override
	@Transactional
	public void delete(Long id) {
		//删除内容
		articleContentService.deleteAll(id);
		//删除扩展属性
		articleExtendService.deleteAll(id);
		//删除文章
		articleDao.delete(id);
	}

	@Override
	@Transactional
	public void update(Long id, Article article) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		//内容列表
		List<ArticleContent> contentList = article.getContentList();
		//扩展属性
		List<ArticleExtend> extendList = article.getExtendList();
		//总页数
		int pageSize = contentList == null ? 0 : contentList.size();
		article.setPageCount(pageSize);
		article.setModifyDate(new Date());
		articleDao.update(article, params);
		
		if (contentList != null && contentList.size() > 0) {
			// 删除文章所有内容
			articleContentService.deleteAll(id);
			for (int index = 0; index < contentList.size(); index ++) {
				//articleContentService.update(contentList.get(index), id, index + 1);
				// 插入文章内容
				ArticleContent content = contentList.get(index);
				content.setIndex(index + 1);
				content.setArticleId(id);
				articleContentService.add(content);
			}
		}
		
		if (extendList != null && extendList.size() > 0) {
			for (ArticleExtend extend : extendList) {
				if (extend == null) {
					continue;
				}
				articleExtendService.update(id, extend.getKey(), extend.getValue(), extend.getType());
			}
		}
	}
	
	@Override
	public void update(Long articleId, Long folderId) {
		Map<String, Object> params = new HashMap<String, Object>(3);
		params.put("id", articleId);
		articleDao.updateFolderId(folderId, params);
	}
	
	@Override
	@PreAudit(level=1, code="A01-001", info="article.find")
	public Article find(Long id) {
		return articleDao.select(id);
	}

	@Override
	@PreAudit(level=1, code="A01-002", info="article.findList")
	public List<Article> findList(Long categoryId, String i18n) {
		Map<String, Object> params = new HashMap<String, Object>(5);
		params.put("categoryId", categoryId);
		params.put("i18n", i18n);
		return articleDao.select(params);
	}

	@Override
	@PreAudit(level=1, code="A01-003", info="article.findList")
	public List<Article> findList(Long categoryId, String i18n, boolean isDraft, boolean isReject, boolean enabled) {
		Map<String, Object> params = new HashMap<String, Object>(11);
		params.put("categoryId", categoryId);
		params.put("i18n", i18n);
		params.put("isDraft", isDraft);
		params.put("isReject", isReject);
		params.put("enabled", enabled);
		return articleDao.select(params);
	}
	
	@Override
	@PreAudit(level=1, code="A02-001", info="article.query")
	public Article query(Long id) {
		Map<String, Object> params = new HashMap<String, Object>(3);
		params.put("id", id);
		List<Article> articleList = articleDao.queryArticle(params);
		return (articleList != null && articleList.size() > 0) ? articleList.get(0) : null; 
	}
	
	@Override
	public Article query(Long id, int index) {
		Map<String, Object> params = new HashMap<String, Object>(5);
		params.put("id", id);
		params.put("index", index);
		List<Article> articleList = articleDao.queryArticle(params);
		return (articleList != null && articleList.size() > 0) ? articleList.get(0) : null; 
	}
	
	@Override
	public Article query(Long id, int index, List<String> nameList) {
		Map<String, Object> params = new HashMap<String, Object>(7);
		params.put("id", id);
		params.put("index", index);
		params.put("nameList", nameList);
		List<Article> articleList = articleDao.queryArticle(params);
		return (articleList != null && articleList.size() > 0) ? articleList.get(0) : null; 
	}
	
	@Override
	@PreAudit(level=1, code="A03-001", info="article.search")
	@PostAudit(level=1, code="A03-001", info="article.search", auditTarget="com.demo.cms.model.Article")
	public ResultSearchResult<Article> search(Long categoryId, String i18n, SearchArgumentSupport args) {
		Map<String, Object> params = new HashMap<String, Object>(7);
		params.put("categoryId", categoryId);
		params.put("i18n", i18n);
		ResultSearchResult<Article> articleResultList = articleDao.search(params, args);
		auditNotes = "ok over";
		return articleResultList;
	}
	@Override
	@PreAudit(level=1, code="A03-002", info="article.search")
	public ResultSearchResult<Article> search(Long categoryId,
												Boolean isComment, 
												Boolean isDraft, 
												Boolean isCheck,
												Boolean isPermission, 
												Boolean enabled, 
												String i18n, SearchArgumentSupport args) {
		Map<String, Object> params = new HashMap<String, Object>(12);
		params.put("categoryId", categoryId);
		params.put("i18n", i18n);
		params.put("isComment", isComment);
		params.put("isDraft", isDraft);
		params.put("isPermission", isPermission);
		params.put("enabled", enabled);
		ResultSearchResult<Article> articleResultList = articleDao.search(params, args);
		return articleResultList;
	}
	
	@Override
	@PreAudit(level=1, code="A03-003", info="article.search")
	@PostAudit(level=1, code="A03-004", info="article.search", auditTarget="com.demo.cms.model.Article")
	public ResultSearchResult<Article> searchActive(Long categoryId, String i18n, String orderBy, int limit) {
		Map<String, Object> params = new HashMap<String, Object>(7);
		params.put("categoryId", categoryId);
		params.put("i18n", i18n);
		// 非草稿
		params.put("isDraft", false);
		// 非被拒绝
		params.put("isReject", false);
		// 可用
		params.put("enabled", true);
		
		params.put("orderBy", orderBy);
		SearchArgumentSupport sas = new SearchArgumentSupport(0, limit);
		ResultSearchResult<Article> articleResults = articleDao.search(params, sas);
		return articleResults;
	}
	
	@Override
	public Article simpleFind(Long id) {
		return articleDao.simpleFind(id);
	}
	
	@Override
	public List<Article> simpleFindList(Long categoryId, SearchArgumentSupport args) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("categoryId", categoryId);
		ResultSearchResult<Article> result = articleDao.search("shortSelect", params, args);
		return result == null ? null : new ArrayList<Article>(result.getResults());
	}
	
	public void setArticleDao(ArticleDao articleDao) {
		this.articleDao = articleDao;
	}

	public void setArticleContentService(ArticleContentService articleContentService) {
		this.articleContentService = articleContentService;
	}

	public void setArticleExtendService(ArticleExtendService articleExtendService) {
		this.articleExtendService = articleExtendService;
	}

	@Override
	public List<Article> _findList(String ssid) {
		if (StringUtils.isNotEmpty(ssid)) {
			return findList(Long.parseLong(ssid, 16), null);
		}
		return null;
	}
}
